package com.example.mq.loader;

import com.example.mq.annotation.MQListener;
import com.example.mq.config.SysMQConfig;
import com.example.mq.dto.MQListenerDto;
import com.example.mq.factory.SysMQFactory;
import com.example.server.service.SysServerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/*
 * @className: SysMQLoader
 * @author: chentao
 * @date: 2025/3/25 下午2:26
 * @Version: 1.0
 * @description:
 */
@Service
public class SysMQLoader implements BeanPostProcessor, DisposableBean, CommandLineRunner {

    Logger logger = LoggerFactory.getLogger(getClass());

    private Map<String, MQListenerDto> listenerMap = new ConcurrentHashMap<String, MQListenerDto>();

    @Resource
    private SysMQConfig sysMQConfig;

    @Resource
    private ApplicationContext applicationContext;

    @Resource
    private SysServerService sysServerService;

    private SysMQFactory sysMQFactory;

    public SysMQFactory getSysMQFactory() {
        return sysMQFactory;
    }

    @Override
    public void destroy() throws Exception {
        this.sysMQFactory.stop();
    }

    @Override
    public void run(String... args) throws Exception {
        Class<?> startClass = Class.forName(sysMQConfig.getLoadClass());
        this.sysMQFactory = (SysMQFactory) startClass.newInstance();
        this.sysMQFactory.init(sysMQConfig, applicationContext, sysServerService);
        this.sysMQFactory.preValidate(this.listenerMap);
        this.sysMQFactory.start(this.listenerMap);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean.getClass().isAnnotationPresent(MQListener.class)) {
            MQListener mqListener = bean.getClass().getAnnotation(MQListener.class);
            this.listenerMap.put(mqListener.queue(), new MQListenerDto(beanName, mqListener));
        }
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}
